﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using PairingMatrix.Common;
using PairingMatrix.Common.Command;
using PairingMatrix.Common.Enum;
using PairingMatrix.Model;
using PairingMatrix.View;
using System.Linq;

namespace PairingMatrix.ViewModel
{
    public class ProjectCardViewModel : ViewModelBase, IProjectCardViewModel
    {
        private readonly ProjectCardModel _model;
        public ObservableCollection<IProjectCardViewModel> SecondaryProjectCards { get; set; }

        public ProjectCardViewModel(ProjectCardModel model)
        {
            this._model = model;
            SecondaryProjectCards = new ObservableCollection<IProjectCardViewModel>();
            _model.PropertyChanged += _model_PropertyChanged;
            _model.SecondaryProjectCards.CollectionChanged += SecondaryProjectCards_CollectionChanged;
            ShowCard = true;
            if (_model.Note !=null && _model.Note.Trim() != "")
                ShowNotes = true;
        }

        void SecondaryProjectCards_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if(e.Action == NotifyCollectionChangedAction.Add)
            {
                var cardWallViewModel = (ICardWallViewModel)ControlRegistry.CardWallControl.DataContext;
                var projectCardModel = (ProjectCardModel)e.NewItems[0];
                SecondaryProjectCards.Add(cardWallViewModel.ProjectCards.First(p => p.CardNumber == projectCardModel.CardNumber));
            }
            if(e.Action == NotifyCollectionChangedAction.Remove)
            {
                var projectCardModel = (ProjectCardModel)e.OldItems[0];
                SecondaryProjectCards.Remove( SecondaryProjectCards.First(sec => sec.CardNumber == projectCardModel.CardNumber));
            }
        }

        private void ResetAllSecondaryProjectCardPositions()
        {
            for (int i = 0; i < SecondaryProjectCards.Count;i++ )
            {
                var secondaryCard = SecondaryProjectCards[i];
                secondaryCard.PositionOnWallOnly = new Point(Position.X, Position.Y + 60 * (i + 1));
            }
        }

        void _model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "AssignedTeamMember1")
                SetAssignedTeamMember1Position();

            if (e.PropertyName == "AssignedTeamMember2")
                SetAssignedTeamMember2Position();

            if (e.PropertyName == "DevStage")
            {
                Position = ((CardWallViewModel)ControlRegistry.CardWallControl.DataContext).GetDefaultPositionAsPerDevelopmentStage(_model.DevStage, _model.Position.Y); ;
            }

            if(e.PropertyName == "Position")
            {
                SetAssignedTeamMember1Position();
                SetAssignedTeamMember2Position();
                ResetAllSecondaryProjectCardPositions();
            }

            if(e.PropertyName == "Note")
            {
                ShowNotes = true;
            }

            if(IsValidProperty(e.PropertyName))
                OnPropertyChanged(e.PropertyName);
        }

        private void SetAssignedTeamMember2Position()
        {
            if(AssignedTeamMember2 != null)
                AssignedTeamMember2.Position = new Point(Position.X + 185, Position.Y + 20);
        }

        private void SetAssignedTeamMember1Position()
        {
            if(AssignedTeamMember1 != null)
                AssignedTeamMember1.Position = new Point(Position.X - 75, Position.Y + 20);
        }

        public int CardNumber
        {
            get { return _model.CardNumber; }
            set
            {
                if (_model.CardNumber == value)
                    return;
                _model.CardNumber = value;
                OnPropertyChanged("CardNumber");
            }
        }

        public int Priority
        {
            get { return _model.Priority; }
            set
            {
                if (_model.Priority == value)
                    return;
                _model.Priority = value;
                OnPropertyChanged("Priority");
            }
        }

        public string Title
        {
            get { return _model.Title; }
            set
            {
                if (_model.Title == value)
                    return;
                _model.Title = value;
                OnPropertyChanged("Title");
            }
        }

        public string Note
        {
            get { return _model.Note; }
            set
            {
                if (_model.Note == value)
                    return;
                _model.Note = value;
                ShowNotes = true;
                OnPropertyChanged("Note");
            }
        }


        private Point _centerPoint;
        public Point CenterPoint 
        {
            get { return _centerPoint; }
            set
            {
                if (_centerPoint == value)
                    return;
                _centerPoint = value;
                OnPropertyChanged("CenterPoint");
            }
        }


        public Point Position
        {
            get { return _model.Position; }
            set
            {
                if (_model.Position == value)
                    return;
                _model.Position = value;
                OnPropertyChanged("Position");
            }
        }


        public Point PositionOnWallOnly
        {
            set
            {
                _model.shallSetProjectOnWall = false;
                _model.Position = value;
            }
        }


        private bool _showHighlighted;
        public bool ShowHighlighted
        {
            get { return _showHighlighted; }
            set
            {
                if (_showHighlighted == value)
                    return;
                _showHighlighted = value;
                OnPropertyChanged("ShowHighlighted");
            }
        }

        private bool _showCard;
        public bool ShowCard
        {
            get { return _showCard; }
            set
            {
                if (_showCard == value)
                    return;
                _showCard = value;
                OnPropertyChanged("ShowCard");
            }
        }

        public TeamMemberModel AssignedTeamMember1
        {
            get { return _model.AssignedTeamMember1; }
            set
            {
                if (_model.AssignedTeamMember1 == value)
                    return;
                _model.AssignedTeamMember1 = value;
                OnPropertyChanged("AssignedTeamMember1");
            }
        }

        public TeamMemberModel AssignedTeamMember2
        {
            get { return _model.AssignedTeamMember2; }
            set
            {
                if (_model.AssignedTeamMember2 == value)
                    return;
                _model.AssignedTeamMember2 = value;
                OnPropertyChanged("AssignedTeamMember2");
            }
        }

        public bool IsCardVisibleInCurrentWall
        {
            get { return _model.IsCardVisibleInCurrentWall; }
        }

        public bool CanAcceptMoreTeamMember()
        {
            return AssignedTeamMember1 == null || AssignedTeamMember2 == null;
        }


        public ProjectCardModel Model
        {
            get { return _model; }
        }

        public StoryStatus DevStage
        {
            get { return _model.DevStage; }
            set 
            { 
                if(_model.DevStage == value)
                    return;
                _model.DevStage = value;
                OnPropertyChanged("DevStage");
            }
        }

        public string StatusInMingle
        {
            get { return _model.StatusInMingle; }
            set
            {
                if (_model.StatusInMingle == value)
                    return;
                _model.StatusInMingle = value;
                OnPropertyChanged("StatusInMingle");
            }
        }

        private RelayCommand _toggleEditModeCommand;
        public RelayCommand ToggleEditModeCommand
        {
            get
            {
                return _toggleEditModeCommand ??
                       (_toggleEditModeCommand = new RelayCommand(param =>
                                                                  {
                                                                      if (IsInEditMode)
                                                                          _model.Save();
                                                                      IsInEditMode = !IsInEditMode;
                                                                  }));
            }
        }

        private bool _isInEditMode;
        public bool IsInEditMode
        {
            get { return _isInEditMode; }
            set
            {
                if (_isInEditMode == value)
                    return;
                _isInEditMode = value;
                OnPropertyChanged("IsInEditMode");
            }
        }



        public int NumberOfSignUps
        {
            get { return _model.NumberOfSignUps; }
        }

        public double DevEstimate
        {
            get { return _model.DevEstimate; }
            set
            {
                if (_model.DevEstimate == value)
                    return;
                _model.DevEstimate = value;
                OnPropertyChanged("DevEstimate");
            }
        }

        public Urgency Urgency
        {
            get { return _model.Urgency; }
            set
            {
                if (_model.Urgency == value)
                    return;
                _model.Urgency = value;
                OnPropertyChanged("Urgency");
            }
        }



        private RelayCommand _removeFromWallCommand;
        public RelayCommand RemoveFromWallCommand
        {
            get
            {
                return _removeFromWallCommand ??
                       (_removeFromWallCommand = new RelayCommand(param => ((ICardWallViewModel)
                                                                            ControlRegistry.CardWallControl.DataContext).RemoveProjectCardFromWall(Registry.CurrentDate, CardNumber)));
            }
        }

        private RelayCommand _toggleNotesVisibilityCommand;
        public RelayCommand ToggleNotesVisibilityCommand
        {
            get
            {
                return _toggleNotesVisibilityCommand ??
                       (_toggleNotesVisibilityCommand = new RelayCommand(param => ShowNotes = !ShowNotes));
            }
        }

        private int _zIndex;
        public int ZIndex
        {
            get { return _zIndex; }
            set
            {
                if (_zIndex == value)
                    return;
                _zIndex = value;
                OnPropertyChanged("ZIndex");
            }
        }


        private bool _showNotes;
        public bool ShowNotes
        {
            get { return _showNotes; }
            set
            {
                if (_showNotes == value)
                    return;
                _showNotes = value;
                OnPropertyChanged("ShowNotes");
            }
        }

        public bool IsSyncing
        {
            get { return _model.IsSyncing; }
            set
            {
                if (_model.IsSyncing == value)
                    return;
                _model.IsSyncing = value;
                if(value == true)
                    ShowCard = true;
                OnPropertyChanged("IsSyncing");
            }
        }

        public ProjectCardModel PrimaryCard
        {
            get { return _model.PrimaryCard; }
            set
            {
                if (_model.PrimaryCard == value)
                    return;
                _model.PrimaryCard = value;
                OnPropertyChanged("PrimaryCard");
            }
        }

        public bool ShowDaysSpentForProjectCards
        {
            get { return _model.ShowDaysSpentForProjectCards; }
            set
            {
                if (_model.ShowDaysSpentForProjectCards == value)
                    return;
                _model.ShowDaysSpentForProjectCards = value;
                OnPropertyChanged("ShowDaysSpentForProjectCards");
            }
        }

    }
}